<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2023/11/1
 * Time: 12:19
 */

namespace app\common\lib;


use App\Exceptions\IndexException;
use Yzh\ApiUserSignServiceClient;
use Yzh\Model\Apiusersign\ApiUserSignContractRequest;
use Yzh\Model\Apiusersign\ApiUserSignRequest;
use Yzh\Model\Apiusersign\GetApiUserSignStatusRequest;
use Yzh\Model\Notify\NotifyRequest;
use Yzh\Model\Payment\CreateAlipayOrderRequest;
use Yzh\NotifyClient;
use Yzh\PaymentClient;

class YunZhangHu2
{
    protected        $config = [];
    protected        $yzhConfig = [];
    protected        $client = [];
    protected static $instance;

    public function __construct()
    {
        $this->config = config('param.yunzhanghu');
        // 配置基础信息
        $this->yzhConfig = \Yzh\Config::newFromArray(array(
            "app_dealer_id" =>  $this->config['dealer_id'],
            "app_broker_id" => $this->config['broker_id'],
            "app_key" => $this->config['app_key'],
            "app_des3_key" => $this->config['des3_key'],
            "app_private_key" => $this->config['private_key'],
            "yzh_public_key" => $this->config['public_key'],
            "sign_type" => "rsa"
        ));
    }

    public static function getInstance()
    {
//        if (is_object(self::$instance)) {
//            return self::$instance;
//        }

        return new self();
    }

    /**
     * 获取协议预览 URL
     */
    public function getUserContract()
    {
        $this->client = new ApiUserSignServiceClient($this->yzhConfig);
        $this->client->setEnv(ApiUserSignServiceClient::ENV_PROD);// 沙箱环境使用 ENV_SANDBOX
        // 配置请求参数
        $request = new ApiUserSignContractRequest(array(
            "dealer_id" => $this->config['dealer_id'],
            "broker_id" => $this->config['broker_id'],
        ));
        // request-id：请求ID，请求的唯一标识
        // 建议平台企业自定义 request-id，并记录在日志中，便于问题发现及排查
        // 如未自定义 request-id，将使用 SDK 中的 random 方法自动生成。注意：random 方法生成的 request-id 不能保证全局唯一，推荐自定义 request-id
        //$request->setRequestID(time().Common::randString(8,1));
        try {
            $response = $this->client->apiUserSignContract($request);
            if ($response->isSuccess()) {
                // 操作成功
                return ['url'=>$response->getData()->getUrl(),'title'=>$response->getData()->getTitle()];
            } else {
                // 失败返回
                throw new \Exception($response->getMessage(),$response->getCode());
            }
        } catch(\Exception $e) {
            // 发生异常
           throw $e;
        }
    }

    /**
     * 用户签约
     * @param $param
     * @return string
     * @throws \Yzh\Exception\ConfigException
     */
    public function userSign($param)
    {
        $this->client = new ApiUserSignServiceClient($this->yzhConfig);
        $this->client->setEnv(ApiUserSignServiceClient::ENV_PROD);// 沙箱环境使用 ENV_SANDBOX
        // 配置请求参数
        $request = new ApiUserSignRequest(array(
            "dealer_id" => $this->config['dealer_id'],
            "broker_id" => $this->config['broker_id'],
            "real_name" => $param['truename'],
            "id_card" => $param['idcard'],
            "card_type" => "idcard",
        ));
        // request-id：请求ID，请求的唯一标识
        // 建议平台企业自定义 request-id，并记录在日志中，便于问题发现及排查
        // 如未自定义 request-id，将使用 SDK 中的 random 方法自动生成。注意：random 方法生成的 request-id 不能保证全局唯一，推荐自定义 request-id
        //$request->setRequestID("requestId");
        try {
            $response = $this->client->apiUserSign($request);
            if ($response->isSuccess()) {
                // 操作成功
                return ['status'=>$response->getData()->getStatus()];
            } else {
                // 失败返回
                throw new \Exception($response->getMessage(),$response->getCode());
            }
        } catch(\Exception $e) {
            // 发生异常
            throw $e;
        }
    }

    /**
     * 获取用户签约状态
     * @param $param
     * @return string
     * @throws \Yzh\Exception\ConfigException
     */
    public function getUserSignStatus($param)
    {
        $this->client = new ApiUserSignServiceClient($this->yzhConfig);
        $this->client->setEnv(ApiUserSignServiceClient::ENV_PROD);// 沙箱环境使用 ENV_SANDBOX
        // 配置请求参数
        $request = new GetApiUserSignStatusRequest(array(
            "dealer_id" => $this->config['dealer_id'],
            "broker_id" => $this->config['broker_id'],
            "real_name" => $param['truename'],
            "id_card" => $param['idcard'],
        ));
        // request-id：请求ID，请求的唯一标识
        // 建议平台企业自定义 request-id，并记录在日志中，便于问题发现及排查
        // 如未自定义 request-id，将使用 SDK 中的 random 方法自动生成。注意：random 方法生成的 request-id 不能保证全局唯一，推荐自定义 request-id
        //$request->setRequestID("requestId");
        try {
            $response = $this->client->getApiUserSignStatus($request);
            if ($response->isSuccess()) {
                // 操作成功0: 未签约
                //1: 已签约
                //2: 已解约
                return ['status'=>$response->getData()->getStatus(),'signed_at'=>$response->getData()->getSignedAt()];
            } else {
                // 失败返回
                throw new \Exception($response->getMessage(),$response->getCode());
            }
        } catch(\Exception $e) {
            // 发生异常
            throw $e;
        }
    }

    /**
     * 支付宝实时支付
     * @param $param
     * @return string
     * @throws \Yzh\Exception\ConfigException
     */
    public function submitAlipayOrder($param)
    {
        $this->client = new PaymentClient($this->yzhConfig);
        $this->client->setEnv(PaymentClient::ENV_PROD);// 沙箱环境使用 ENV_SANDBOX
        // 配置请求参数
        $request = new CreateAlipayOrderRequest(array(
            "dealer_id" => $this->config['dealer_id'],
            "broker_id" => $this->config['broker_id'],
            "order_id" => $param['transfer_order_sn'],
            "real_name" => $param['payee_name'],
            "card_no" => $param['payee_account'],
            "id_card" => $param['payee_idcard'],
            "phone_no" => "",
            "pay" => (string)$param['amount'],
            "pay_remark" => $param['remark']??'',
            "check_name" => "Check",
            "notify_url" => $param['notify_url'],
            "project_id" => ""
        ));
        // request-id：请求ID，请求的唯一标识
        // 建议平台企业自定义 request-id，并记录在日志中，便于问题发现及排查
        // 如未自定义 request-id，将使用 SDK 中的 random 方法自动生成。注意：random 方法生成的 request-id 不能保证全局唯一，推荐自定义 request-id
        //$request->setRequestID("requestId");
        try {
            $response = $this->client->createAlipayOrder($request);
            $response->getCode();
            if ($response->isSuccess()) {
                // 操作成功
                return [
                    'order_id'=>$response->getData()->getOrderId(),
                    'ref'=>$response->getData()->getRef(),
                    'pay'=>$response->getData()->getPay(),
                ];
            } else {
                // 失败返回
                throw new \Exception($response->getMessage(),$response->getCode());
            }
        } catch(\Exception $e) {
            // 发生异常
            throw $e;
        }
    }

    public function payStatusNotify($param)
    {
        $notifyClient = new NotifyClient($this->yzhConfig);
        // 异步回调参数
        $data = $param['data'];
        $mess = $param['mess'];
        $timestamp = $param['timestamp'];
        $sign = $param['sign'];
        $notifyReq = new NotifyRequest ($data, $mess, $timestamp, $sign) ;
        // 发起验签解密
        try {
            $result = $notifyClient->verifyAndDescrype($notifyReq);
            if ($result) {
                // 验签通过、解密成功
                return json_decode($result->getData(),true);
            }
        } catch(\Exception $e){
            // 发生异常
            throw $e;
        }
    }
}